package org.dprojects.iwebshare.main;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.dprojects.iwebshare.db.util.HibernateUtil;
import org.dprojects.iwebshare.ui.manager.UiManager;
import org.dprojects.iwebshare.ui.window.LoginWindow;
import org.dprojects.iwebshare.util.BeanContextUtil;
import org.hibernate.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vaadin.Application;
import com.vaadin.service.ApplicationContext.TransactionListener;
import com.vaadin.terminal.gwt.server.HttpServletRequestListener;
import com.vaadin.ui.Table;
import com.vaadin.ui.Window;
import com.vaadin.ui.Window.CloseEvent;

public class iWebShareApplication extends Application implements HttpServletRequestListener,Window.CloseListener {
	/**
	 * 
	 */
	private static final long serialVersionUID = -2912455041485372927L;
	private static Logger log = LoggerFactory.getLogger(iWebShareApplication.class);
	private Table table;
	private static int tableIndex = 1;
	
	private String currentUser = null;

	private static ThreadLocal<iWebShareApplication> threadLocal = new ThreadLocal<iWebShareApplication>(); 
	
	@Override
	public void init() {
		setTheme("runo");
		attachVaadinTransactionListener();
		//initWindow();
		//attachVaadinApplicationCloseListerner();
		//MAIN_APPLICATION=this;
		
		setInstance(this);
		LoginWindow main=new LoginWindow();
		setMainWindow(main);
	}

	/**
	 * We are using session-per-request pattern with Hibernate. By using
	 * Vaadin's transaction listener we can easily ensure that session is closed
	 * on each request without polluting our program code with extra logic.
	 */
	private void attachVaadinTransactionListener() {
		getContext().addTransactionListener(new TransactionListener() {
			/**
			 * 
			 */
			private static final long serialVersionUID = -7727149551252570994L;

			public void transactionEnd(Application application,
					Object transactionData) {
				// Transaction listener gets fired for all (Http) sessions
				// of Vaadin applications, checking to be this one.
				if (application == iWebShareApplication.this) {
					closeSession();
					threadLocal.remove();
				}
			}

			public void transactionStart(Application application,
					Object transactionData) {
			}
		});
	}

	private void closeSession() {
		Session sess = HibernateUtil.getSessionFactory().getCurrentSession();
		if (sess.getTransaction().isActive()) {
			sess.getTransaction().commit();
		}
		if (sess.isOpen()) {
			sess.close();
		}
	}

	/*
	private void initWindow() {
		// setMainWindow(null);

		WindowManager windowManager = (WindowManager) BeanContextUtil
				.getBean("module.window.manager");
		setMainWindow(windowManager.getMainWindow());
*/
		/*
		 * Window mainWindow = new Window("Kalel Application");
		 * setMainWindow(mainWindow);
		 * 
		 * 
		 * Label label = new Label("Hello Vaadin user");
		 * mainWindow.addComponent(label);
		 * 
		 * Button b = new Button("TEST"); b.addListener(new ClickListener() {
		 * 
		 * 
		 * private static final long serialVersionUID = 1936124464825209632L;
		 * 
		 * @Override public void buttonClick(ClickEvent event) { User u = new
		 * User(); u.setUsername("ciccio1"); u.setPassword("welcome");
		 * 
		 * Directory dir = new Directory(); dir.setName("testdir");
		 * dir.setPath("/tmp");
		 * 
		 * List<Directory> dirs = new ArrayList<Directory>(); dirs.add(dir);
		 * 
		 * u.setDirs(dirs);
		 * 
		 * Session session = HibernateUtil.getSession(); session.save(dir);
		 * session.save(u);
		 * 
		 * log.info("A user "+u.getUsername()+" is created");
		 * 
		 * table.addItem(getTableItem(new String[]{"username"},u),new
		 * Integer(tableIndex++)); } });
		 * 
		 * mainWindow.addComponent(b);
		 * 
		 * mainWindow.addComponent(createTable());
		 */
	//}

	
	/*
	public Table createTable() {
		table = new Table("Test Table");
		table.addContainerProperty("Username", String.class, null);
		table.setColumnWidth("Username", 100);
		// table.addContainerProperty("Password", String.class, null);
		// table.addContainerProperty("Dir", String.class, null);
		table.setWidth(200, Sizeable.UNITS_PIXELS);

		Session session = HibernateUtil.getSession();
		List<User> l = session.createQuery("from User").list();

		if (l != null) {
			for (User p1 : l) {
				// table.addItem(new Object[] { p1.getUsername(),
				// p1.getPassword(), p1.getDirs().get(0).getPath() },new
				// Integer(i++));
				// table.addItem(getTableItem(new
				// String[]{"username","password","username"},p1),new
				// Integer(i++));
				table.addItem(getTableItem(new String[] { "username" }, p1),
						new Integer(tableIndex++));
			}
		}

		return table;
	}

	public Object[] getTableItem(String[] nameFields, Object obj) {
		Object[] result = new Object[nameFields.length];
		String methodName = "";
		for (int i = 0; i < nameFields.length; i++) {
			try {
				methodName = nameFields[i].substring(0, 1);
				methodName = "get" + methodName.toUpperCase()
						+ nameFields[i].substring(1, nameFields[i].length());
				Method m = obj.getClass().getMethod(methodName);
				result[i] = m.invoke(obj);
			} catch (SecurityException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return result;
	}
	*/
	
	// @return the current application instance	  	
	public static iWebShareApplication getInstance() {
		return threadLocal.get();
	}
	
	// @return the current application instance	  	
	public static void setInstance(iWebShareApplication application) {
		if(getInstance()==null)
			threadLocal.set(application);
	}

	public void onRequestStart(HttpServletRequest request,
			HttpServletResponse response) {
		iWebShareApplication.setInstance(this);
	}

	public void onRequestEnd(HttpServletRequest request,
			HttpServletResponse response) {
		threadLocal.remove();	
	}

	public void authenticate(String login, String password) throws Exception{
		{
	        if ( !"user".equals ( login ) && !password.equals ( "qwerty" ))
	        {
	            throw new Exception ("Login failed !");
	        }
	        
	        currentUser = login;
	        UiManager ui= (UiManager) BeanContextUtil.getContext().getBean("ui.manager");
			ui.createUi();
	    }
		
	}

	public void windowClose(CloseEvent e) {
		getMainWindow().getApplication().close();
	}

}
